package cn.jinjimi.app.util;

import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;

import cn.jinjimi.base.Task.TaskExecutor;
import cn.jinjimi.base.util.GsonUtils;
import cn.jinjimi.base.util.StringUtils;
import cn.jinjimi.base.util.ToastUtils;
import cn.jinjimi.app.AccountManager;
import cn.jinjimi.app.R;
import cn.jinjimi.app.controller.CommonController;
import cn.jinjimi.app.controller.event.DataEvent;
import cn.jinjimi.app.controller.event.UploadResultEvent;
import cn.jinjimi.app.entity.PhotoInfo;
import cn.jinjimi.app.entity.PhotoList;
import cn.jinjimi.app.main.dialog.LoadingDialog;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import bolts.Continuation;
import bolts.Task;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

/**
 * 上传图片
 * <p/>
 * 上传多图使用多线程上传
 * <p/>
 * Created by Jinsen on 15/12/29.
 */
public class UploadPhotosUtil {

    private final static int MAX_WIDTH = 1920;
    private final static int MAX_HEIGHT = 1920;
    private final static Object LOCK = new Object();

    /**
     * 上传个人头像和半身照 客户头像
     *
     * @param context
     * @param filePath       上传的图片地址
     * @param url            上传的图片地址
     * @param uploadListener 回调接口
     */
    public static void upLoad(final Context context, final String filePath, String url, final uploadListener uploadListener) {
        upLoad(context, filePath, url, "", uploadListener);
    }

    /**
     * * 上传个人荣誉照片
     *
     * @param context
     * @param filePath       上传的图片地址
     * @param url            上传的图片地址
     * @param name           图片名称
     * @param uploadListener 回调接口
     */
    public static void upLoad(final Context context,
                              final String filePath,
                              String url,
                              String name,
                              final uploadListener uploadListener) {
        HashMap<String, Object> params = new HashMap<String, Object>();

        params.put("ssoid", AccountManager.getInstance().getAccount().ssoid);
        RequestBody rb = RequestBody.create(MediaType.parse("multipart/form-data"), new File(filePath));
        MultipartBody.Part part = MultipartBody.Part.createFormData("file", "image.jpg", rb);
        params.put("file", part);

        if (!TextUtils.isEmpty(name)) {
            params.put("name", name);
        }

        LoadingDialog.show(context, context.getString(R.string.uploading_wait));

        CommonController.uploadFile(url, params).continueWith(new Continuation<UploadResultEvent, Void>() {
            @Override
            public Void then(final Task<UploadResultEvent> task) throws Exception {
                TaskExecutor.runTaskOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (context != null && !((Activity) context).isFinishing()) {

                            if(task.isCompleted()) {
                                UploadResultEvent event = task.getResult();

                                if (event!=null && event.state == DataEvent.SUCC) {

                                    LoadingDialog.dispose();
                                    ToastUtils.toastMessage(context, context.getString(R.string.upload_succ));

                                    if (uploadListener != null)
                                        uploadListener.onSuccess((String) event.data);
                                } else {

                                    LoadingDialog.dispose();
                                    ToastUtils.toastMessage(context, context.getString(R.string.upload_fail));
                                    if (uploadListener != null)
                                        uploadListener.onFailure();
                                }
                            }
                        }
                    }
                });
                return null;
            }
        });

    }

    /**
     * 上传多张图片
     *
     * @param context
     * @param url
     * @param photoList
     * @param listener
     */
    public static void uploadPhotos(final Context context,
                                    final String url,
                                    final List<PhotoInfo> photoList,
                                    final UploadPhotosListener listener) {

        if (StringUtils.isEmpty(url) || photoList == null || photoList.isEmpty()) {
            listener.uploadFail();
            return;
        }

        final int uploadSize = photoList.size();
        final List<PhotoInfo> success = new ArrayList<>();
        final List<PhotoInfo> fail = new ArrayList<>();

        LoadingDialog.showLast(context, "正在上传图片(0/" + uploadSize + ")");

        Task.forResult(photoList).continueWithTask(new Continuation<List<PhotoInfo>, Task<Void>>() {

            @Override
            public Task<Void> then(Task<List<PhotoInfo>> task) throws Exception {

                List<PhotoInfo> list = task.getResult();

                List<Task<UploadResultEvent>> tasks = new ArrayList<>();

                if (list != null && list.size() > 0) {

                    LoadingDialog.showLast(context, "正在上传图片(0/" + uploadSize + ")");

                    for (final PhotoInfo photo : list) {

                        Task<UploadResultEvent> t = newUploadTask(url, photo)
                                .onSuccess(new Continuation<UploadResultEvent, UploadResultEvent>() {
                                    @Override
                                    public UploadResultEvent then(Task<UploadResultEvent> task) throws Exception {

                                        UploadResultEvent event = task.getResult();

                                        if (event.state == DataEvent.SUCC) {
                                            String str = (String) event.data;
                                            PhotoList pl = GsonUtils.fromJson(str, PhotoList.class);
                                            if (pl != null) {
                                                synchronized (LOCK) {
                                                    success.addAll(pl.getAttachements());
                                                }
                                            }

                                        }

                                        if (event.state == DataEvent.FAIL) {
                                            synchronized (LOCK) {
                                                fail.add(photo);
                                            }
                                        }

                                        LoadingDialog.showLast(context, "正在上传图片(" + (success.size() + fail.size()) + "/" + uploadSize + ")");

                                        return null;
                                    }
                                }, Task.UI_THREAD_EXECUTOR);

                        tasks.add(t);
                    }
                }

                return Task.whenAll(tasks);
            }
        }).onSuccess(new Continuation<Void, Void>() {
            @Override
            public Void then(Task<Void> task) throws Exception {
                LoadingDialog.dispose();
                if (listener != null) {
                    listener.uploadDone(photoList, success, fail.size());
                }
                return null;
            }
        });

    }

    private static Task<UploadResultEvent> newUploadTask(final String url, final PhotoInfo photoInfo) {
        String path = photoInfo.getAbsolutePath();
        String newPath = BitmapUtils.compressByQuality(BitmapUtils.compressBySize(path, MAX_WIDTH, MAX_HEIGHT), 70);

        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("file" + 0, new File(newPath));

        return CommonController.uploadFile(url, params);
    }


    /* 监听上传多张图片结果 */
    public interface UploadPhotosListener {

        void uploadFail();

        void uploadDone(List<PhotoInfo> oldPhotos, List<PhotoInfo> photoInfos, int failCount);
    }

    /* 监听上传单张图片结果 */
    public interface uploadListener {
        void onSuccess(String responseInfo);

        void onFailure();
    }

}
